package com.example.trtcdemo;

import static com.tencent.trtc.TRTCCloudDef.TRTC_APP_SCENE_LIVE;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.tencent.liteav.TXLiteAVCode;
import com.tencent.rtmp.ui.TXCloudVideoView;
import com.tencent.trtc.TRTCCloud;
import com.tencent.trtc.TRTCCloudDef;
import com.tencent.trtc.TRTCCloudListener;

import org.json.JSONException;
import org.json.JSONObject;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class LiveActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String             TAG                     = "LiveActivity";
    private TRTCCloudDef.TRTCParams mTRTCParams;
    private boolean mIsFrontCamera = true;
    private TRTCCloud mTRTCCloud;
    private String mUserId,mRoomId,mPkUserId,mPkRoomId;
    private TXCloudVideoView mLocalTxVideo,mRemoteTxVideo1;
    private EditText mEtPKRoomId,mEtPKUserId;
    private LinearLayout editInfoPk;
    private Button mBtStartPk, mBtStartPush, mBtStartCdn, mBtStartMix;
    private ImageView ivBack;
    private String mStreamId = "";//自定义流id
    private List<String> mRemoteUidList;
    private boolean isPush = true;//是否推流状态
    private boolean isPK = false;//是否pk状态
    private boolean isPushCDN = true;//是否推送cdn
    private boolean isMixStream = true;//是否混流

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_live);
        getSupportActionBar().hide();
        handleIntent();
        initView();
        enterRoom();
    }

    private void initView() {
        mRemoteUidList = new ArrayList<>();
        mLocalTxVideo = findViewById(R.id.txcvv_main_local);
        mRemoteTxVideo1 = findViewById(R.id.txcvv_video_remote1);
//        mRemoteTxVideo2 = findViewById(R.id.txcvv_video_remote2);
//        mRemoteTxVideo3 = findViewById(R.id.txcvv_video_remote3);
        editInfoPk = findViewById(R.id.ll_edit_info);
        mBtStartPk = findViewById(R.id.btn_start_pk);
        mBtStartPush = findViewById(R.id.btn_start_push);
        mEtPKRoomId = findViewById(R.id.et_remote_room_id);
        mEtPKUserId = findViewById(R.id.et_remote_user_id);
        mBtStartCdn = findViewById(R.id.btn_start_cdn);
        mBtStartMix = findViewById(R.id.btn_start_mix);
        ivBack = findViewById(R.id.iv_back);
        ivBack.setOnClickListener(this);
        mBtStartPk.setOnClickListener(this);
        mBtStartPush.setOnClickListener(this);
        mBtStartCdn.setOnClickListener(this);
        mBtStartMix.setOnClickListener(this);
    }

    /**
     * 开始PK
     */
    private void startPK(){
        mPkRoomId = mEtPKRoomId.getText().toString();
        mPkUserId = mEtPKUserId.getText().toString();
        if(!TextUtils.isEmpty(mPkRoomId) && !TextUtils.isEmpty(mPkUserId)){
            if(isPK){
                mBtStartPk.setText(getString(R.string.connectotherroom_start_pk));
                mTRTCCloud.DisconnectOtherRoom();
                isPK = false;
            }else{
                try {
                    JSONObject jsonObj = new JSONObject();
                    jsonObj.put("strRoomId", mPkRoomId);
                    jsonObj.put("userId", mPkUserId);
                    mTRTCCloud.ConnectOtherRoom(jsonObj.toString());
                    mBtStartPk.setText(R.string.connectotherroom_stop_pk);
                    isPK = true;
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }else{
            Toast.makeText(LiveActivity.this, getString(R.string.connectotherroom_please_input_roomid_and_userid), Toast.LENGTH_SHORT).show();
        }
    }

    private void enterRoom() {
        if (TextUtils.isEmpty(mRoomId)
                || TextUtils.isEmpty(mUserId)) {
            Toast.makeText(LiveActivity.this, getString(R.string.live_room_input_error_tip), Toast.LENGTH_LONG).show();
            return;
        }
        mTRTCCloud = TRTCCloud.sharedInstance(getApplicationContext());
        mTRTCCloud.setListener(new TRTCCloudImplListener(LiveActivity.this));
        mTRTCParams = new TRTCCloudDef.TRTCParams();
        mTRTCParams.sdkAppId = GenerateTestUserSig.SDKAPPID;
        mTRTCParams.userId = mUserId;
        mTRTCParams.roomId = Integer.parseInt(mRoomId);
        mTRTCParams.userSig = GenerateTestUserSig.genTestUserSig(mTRTCParams.userId);
        mTRTCParams.role = TRTCCloudDef.TRTCRoleAnchor;

        mTRTCCloud.startLocalPreview(mIsFrontCamera, mLocalTxVideo);
        mTRTCCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT);
        mTRTCCloud.enterRoom(mTRTCParams, TRTC_APP_SCENE_LIVE);
        mTRTCCloud.startPublishing(mStreamId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);
//        setMixConfigLeftRight();
    }

    protected void exitRoom() {
        if (mTRTCCloud != null) {
            mTRTCCloud.stopLocalAudio();
            mTRTCCloud.stopLocalPreview();
            mTRTCCloud.exitRoom();
            mTRTCCloud.setListener(null);
        }
        mTRTCCloud = null;
        TRTCCloud.destroySharedInstance();
    }

    private void handleIntent() {
        Intent intent = getIntent();
        if (null != intent) {
            if (intent.getStringExtra(Constant.USER_ID) != null) {
                mUserId = intent.getStringExtra(Constant.USER_ID);
                mStreamId = mUserId;
            }
            if (intent.getStringExtra(Constant.ROOM_ID) != null) {
                mRoomId = intent.getStringExtra(Constant.ROOM_ID);
            }
        }
    }

    /**
     * 设置全手动排版模式
     * 具体使用方式见<a href="https://cloud.tencent.com/document/product/647/16827">云端混流转码</a>
     */
    private void setMixConfigManual(List<String> mRemoteUidList) {
        TRTCCloudDef.TRTCTranscodingConfig config = new TRTCCloudDef.TRTCTranscodingConfig();
        config.videoWidth      = 720;
        config.videoHeight     = 1280;
        config.videoBitrate    = 1500;
        config.videoFramerate  = 20;
        config.videoGOP        = 2;
        config.audioSampleRate = 48000;
        config.audioBitrate    = 64;
        config.audioChannels   = 2;
        config.streamId        = mStreamId;
        config.appId           = GenerateTestUserSig.APPID;
        config.bizId           = GenerateTestUserSig.BIZID;
        config.backgroundColor = 0x000000;
        config.backgroundImage = null;

        config.mode = TRTCCloudDef.TRTC_TranscodingConfigMode_Manual;
        config.mixUsers = new ArrayList<>();

//       主播自己
        TRTCCloudDef.TRTCMixUser mixUser = new TRTCCloudDef.TRTCMixUser();
        mixUser.userId = mUserId;
        mixUser.zOrder = 0;
        mixUser.x = 0;
        mixUser.y = 0;
        mixUser.width = 360;
        mixUser.height = 640;
        mixUser.roomId = null;
        mixUser.inputType = TRTCCloudDef.TRTC_MixInputType_AudioVideo;
        config.mixUsers.add(mixUser);


        TRTCCloudDef.TRTCMixUser remote = new TRTCCloudDef.TRTCMixUser();
        remote.userId = mRemoteUidList.get(0);
        remote.streamType = TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG;
        remote.zOrder = 1;
        remote.x      = 360;
        remote.y      = 0;
        remote.width  = 360;
        remote.height = 640;
        remote.roomId = mPkRoomId;
        mixUser.inputType = TRTCCloudDef.TRTC_MixInputType_AudioVideo;
        config.mixUsers.add(remote);

        mTRTCCloud.setMixTranscodingConfig(config);
    }


    /**
     * 设置混流预排版模式
     * 具体使用方式见<a href="https://cloud.tencent.com/document/product/647/16827">云端混流转码</a>
     */
    private void setMixConfigLeftRight() {
        TRTCCloudDef.TRTCTranscodingConfig config = new TRTCCloudDef.TRTCTranscodingConfig();
        config.videoWidth      = 720;
        config.videoHeight     = 640;
        config.videoBitrate    = 1500;
        config.videoFramerate  = 20;
        config.videoGOP        = 2;
        config.audioSampleRate = 48000;
        config.audioBitrate    = 64;
        config.audioChannels   = 2;
        config.streamId        = mStreamId;

        config.mode = TRTCCloudDef.TRTC_TranscodingConfigMode_Template_PresetLayout;
        config.mixUsers = new ArrayList<>();

//       主播自己
        TRTCCloudDef.TRTCMixUser mixUser = new TRTCCloudDef.TRTCMixUser();
        mixUser.userId = "$PLACE_HOLDER_LOCAL_MAIN$";
        mixUser.zOrder = 0;
        mixUser.x = 0;
        mixUser.y = 0;
        mixUser.width = 360;
        mixUser.height = 640;
        mixUser.roomId = null;
        config.mixUsers.add(mixUser);


        //连麦者画面位置
        TRTCCloudDef.TRTCMixUser remote = new TRTCCloudDef.TRTCMixUser();
        remote.userId = "$PLACE_HOLDER_REMOTE$";
        remote.streamType = TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG;
        remote.zOrder = 1;
        remote.x      = 360;
        remote.y      = 0;
        remote.width  = 360;
        remote.height = 640;
        remote.roomId = mRoomId;
        config.mixUsers.add(remote);

        mTRTCCloud.setMixTranscodingConfig(config);
    }


    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_start_pk:
                startPK();
                break;
            case R.id.btn_start_push:
                isPush = !isPush;
                if (isPush){
                    mTRTCCloud.startLocalPreview(mIsFrontCamera, mLocalTxVideo);
                    mTRTCCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT);
                    mBtStartPush.setText(getString(R.string.connectotherroom_stop_push));
                }else {
                    mTRTCCloud.stopLocalPreview();
                    mTRTCCloud.stopLocalAudio();
                    mBtStartPush.setText(getString(R.string.connectotherroom_start_push));
                }
                break;
            case R.id.iv_back:
                finish();
                break;
            case R.id.btn_start_cdn:
                isPushCDN = !isPushCDN;
                if (isPushCDN){
                    mTRTCCloud.startPublishing(mStreamId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);
                    setMixConfigManual(mRemoteUidList);
                    mBtStartCdn.setText(getString(R.string.connectotherroom_stop_cdn));
                }else {
                    mTRTCCloud.stopPublishing();
                    mTRTCCloud.setMixTranscodingConfig(null);
                    mBtStartCdn.setText(getString(R.string.connectotherroom_start_cdn));
                }
                break;
            case R.id.btn_start_mix:
                isMixStream = !isMixStream;
                if (isMixStream){
                    if (mRemoteUidList.size()<=0){
                        Toast.makeText(LiveActivity.this,getString(R.string.pushcdn_anchor_mixconfig_disabled),Toast.LENGTH_LONG);
                    }else {
                        setMixConfigManual(mRemoteUidList);
//                        setMixConfigLeftRight();
                        mBtStartMix.setText(getString(R.string.connectotherroom_stop_mix));
                    }
                }else {
                    mTRTCCloud.setMixTranscodingConfig(null);
                    mBtStartMix.setText(getString(R.string.connectotherroom_start_mix));
                }
                break;
        }
    }

    /**
     * sdk的回调监听
     */
    protected class TRTCCloudImplListener extends TRTCCloudListener {

        private WeakReference<LiveActivity> mContext;

        public TRTCCloudImplListener(LiveActivity activity) {
            super();
            mContext = new WeakReference<>(activity);
        }

        @Override
        public void onRemoteUserEnterRoom(String userId) {
        }

        @Override
        public void onRemoteUserLeaveRoom(String userId, int reason) {
        }

        @Override
        public void onUserVideoAvailable(String userId, boolean available) {
            Log.d(TAG, "onUserVideoAvailable  available " + available + " userId " + userId);
            if (available) {
                mTRTCCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, mRemoteTxVideo1);
                mRemoteUidList.add(userId);

                setMixConfigManual(mRemoteUidList);
            } else {
                mTRTCCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);
                mRemoteUidList.remove(userId);
                mTRTCCloud.setMixTranscodingConfig(null);
            }
        }

        @Override
        public void onStartPublishing(int err, String errMsg) {
            super.onStartPublishing(err, errMsg);
            if (err == 0){
                Log.d(TAG,"开始旁路成功");
            }else {
                Log.d(TAG,"开始旁路失败原因："+errMsg);
            }
        }

        @Override
        public void onStopPublishing(int err, String errMsg) {
            super.onStopPublishing(err, errMsg);
            if (err == 0){
                Log.d(TAG,"关闭旁路成功");
            }else {
                Log.d(TAG,"关闭旁路失败原因："+errMsg);
            }
        }

        @Override
        public void onSetMixTranscodingConfig(int err, String errMsg) {
            super.onSetMixTranscodingConfig(err, errMsg);
            if (err == 0){
                Log.d(TAG,"设置混流参数成功");
            }else {
                Log.d(TAG,"设置混流参数失败原因："+errMsg);
            }
        }

        @Override
        public void onError(int errCode, String errMsg, Bundle extraInfo) {
            Log.d(TAG, "sdk callback onError");
            LiveActivity activity = mContext.get();
            if (activity != null) {
                Toast.makeText(activity, "onError: " + errMsg + "[" + errCode+ "]" , Toast.LENGTH_SHORT).show();
                if (errCode == TXLiteAVCode.ERR_ROOM_ENTER_FAIL) {
                    activity.exitRoom();
                }
            }
        }

        @Override
        public void onEnterRoom(long result) {
            super.onEnterRoom(result);
        }

        @Override
        public void onExitRoom(int reason) {
            super.onExitRoom(reason);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        exitRoom();
    }
}